# toolkit for matrix
import os

import numpy as np
CNfontFile = '/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc'
CNFontSupported = os.path.isfile(CNfontFile)
from matplotlib.font_manager import FontProperties
if CNFontSupported:
    fontP = FontProperties(fname=CNfontFile)
else:
    fontP = FontProperties()
fontP.set_size('medium')

import matplotlib
matplotlib.rcParams['axes.unicode_minus'] = False

os.environ['MATPLOTLIB_USE'] = 'tkagg'
matplotlib.use(os.environ['MATPLOTLIB_USE'])
import matplotlib.pyplot as plt

#Convert match result to matrix
#x dimension definition:
# xidx: select which buckets as x index, defult is the last element
# xstart: value as start of x
# xlen: if string, only use first xlen character
#y dimension:
# yidx: which value as y index
def res2matrix(res, xstart=None, verbose=0, xlen=4, yidx=1, xidx=-1, xsort=True):
    x = []
    y = []
    lgt = []

    dim = len(res[0][0])
    if dim > 2: raise Exception("dimension > 2 is not supported!")

    h = {}
    xh = {}
    lh = {}
    #generate xh, lh, h
    if xidx == -1: xidx = dim - 1
    for r in res:
        if verbose: print(r)
        for idx in range(dim):
            v = list(r[0][idx].values())[0]
            if idx == xidx:
                if type(v) == type('') and xlen: v=v[0:xlen]
                xv = v
                if v not in xh: xh[v] = 1
            else:
                if v not in lh: lh[v] = 1
                lv= v
        if xv not in h: h[xv] = {}
        if dim > 1:
            h[xv][lv] = r[1:]
        else:
            h[xv] = r[1:]

    #generate x,lgt
    x = list(xh.keys())
    if xsort: x.sort()

    offset = 0
    if xstart is not None and xstart in x:
        offset = x.index(xstart)
    x = x[offset:]

    lgt = list(lh.keys())

    #generate y
    if dim == 1:
        for xv in x:
            y.append(h[xv][yidx-1])
    else:
        for xv in x:
            yv = []
            for lv in lgt:
                if lv not in h[xv]: yv.append(0)
                else: yv.append(h[xv][lv][yidx-1])
            y.append(yv)
    x = np.array(x)
    y = np.array(y)

    if verbose: print(x);print(y);print(lgt)
    return (x,y,lgt)

def mark_xy(x,y,fmtstr="%2.3f",color='ro'):
    plt.text(x,y,fmtstr%(y))
    plt.plot(x,y,color)

def plot_xy_line(x, y, legend=None, xlabel='',ylabel='',title='', grid=True, marklimit=False, cgt=[], linestyle='.-'):
    if cgt:
        for j in range(0, len(y[0])):
            y1 = []
            for i in range(0, len(x)):
                y1.append(y[i][j])
            plt.plot(x,y1,'.-',color=cgt[j])
    else:
        plt.plot(x, y, linestyle)
    plt.xlabel(xlabel,fontproperties=fontP)
    plt.ylabel(ylabel,fontproperties=fontP)
    if legend is not None:
        plt.legend(legend, prop = fontP)
    plt.title(title,fontproperties=fontP)
    plt.grid(grid)

    if marklimit:
        miny = y.min(axis=0)
        maxy = y.max(axis=0)
        minyi = y.argmin(axis=0)
        maxyi = y.argmax(axis=0)
        minmax = np.hstack((maxy,miny))
        minmaxi = np.hstack((maxyi,minyi))
        N = len(minmax)
        for i in range(N):
            mark_xy(x[minmaxi[i]],minmax[i])

def sort_y(x, y):
    sidx = list(reversed(np.argsort(y)))
    if type(x) == type([]): x = np.array(x)
    x = x[sidx]
    y = y[sidx]
    return (x,y)

def plot_xy_pie(x, y, title=''):
    plt.title(title, fontproperties=fontP)
    x,y = sort_y(x,y)
    plt.pie(y, autopct='%1.1f%%', startangle=90, counterclock=False)
    plt.legend(x, loc="best", prop = fontP)
